<?php

namespace app\comapi\library;

use app\common\facade\Token;
use app\common\model\banxi\student\Student;
use ba\Random;
use think\facade\Config;
use Throwable;

/**
 * 公共权限类（会员权限类）
 * @property int $id         会员ID
 * @property string $username   会员用户名
 * @property string $nickname   会员昵称
 * @property string $email      会员邮箱
 * @property string $mobile     会员手机号
 * @property string $password   密码密文
 * @property string $salt       密码盐
 */
class Auth extends \app\common\library\Auth
{

    public const TOKEN_TYPE = 'teacher'; //学员

    /**
     * 允许输出的字段
     * @var array
     */
    protected array $allowFields = [];

    public function __construct(array $config = [])
    {
        parent::__construct(array_merge([
        ], $config));
        $this->setKeepTime((int)Config::get('buildadmin.teacher_token_keep_time'));
    }

    /**
     * 根据Token初始化会员登录态
     * @param $token
     * @return bool
     * @throws Throwable
     */
    public function init($token): bool
    {
        $tokenData = Token::get($token);
        if ($tokenData) {
            /**
             * 过期检查，过期则抛出 @see TokenExpirationException
             */
            Token::tokenExpirationCheck($tokenData);
            $userId = intval($tokenData['user_id']);
            //学员
            if ($tokenData['type'] == self::TOKEN_TYPE && $userId > 0) {
                $this->model = Student::where('id', $userId)->find();
                if (!$this->model) {
                    $this->setError('Account not exist');
                    return false;
                }
                if ($this->model->status != 1) {
                    $this->setError('Account disabled');
                    return false;
                }
                $this->token = $token;
                $this->loginSuccessful();
                return true;
            }
        }
        $this->reset();
        $this->setError('Token login failed');
        return false;
    }

    public function loginSuccessful(): bool
    {
        if (!$this->model) {
            return false;
        }
        $this->model->startTrans();
        try {
            $this->model->last_login_time = date('Y-m-d H:i:s');
            $this->model->last_login_ip = request()->ip();
            $this->model->save();
            $this->loginEd = true;

            if (!$this->token) {
                $this->setToken();
            }
            $this->model->commit();
        } catch (Throwable $e) {
            $this->model->rollback();
            $this->setError($e->getMessage());
            return false;
        }
        return true;
    }

    /**
     * 设置Token
     * @return bool
     */
    public function setToken(): bool
    {
        $this->token = Random::uuid();
        Token::set($this->token, self::TOKEN_TYPE, $this->model->id, $this->keepTime);
        return true;
    }

    /**
     * 清理Token
     * @return bool
     */
    public function clearToken(): bool
    {
        // 清理 token
        if (Config::get('buildadmin.client_sso')) {
            Token::clear(self::TOKEN_TYPE, $this->model->id);
            Token::clear(self::TOKEN_TYPE . '-refresh', $this->model->id);
        }
        return true;
    }

    /**
     * 退出登录
     * @return bool
     */
    public function logout(): bool
    {
        if (!$this->loginEd) {
            $this->setError('You are not logged in');
            return false;
        }
        return $this->reset();
    }

    /**
     * 属性重置（注销、登录失败、重新初始化等将单例数据销毁）
     */
    protected function reset(bool $deleteToken = true): bool
    {
        if ($deleteToken && $this->token) {
            Token::delete($this->token);
        }

        $this->token = '';
        $this->loginEd = false;
        $this->model = null;
        $this->refreshToken = '';
        $this->setError('');
        $this->setKeepTime((int)Config::get('buildadmin.teacher_token_keep_time'));
        return true;
    }
}